package com.xxx.control.base

import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.viewbinding.ViewBinding
import com.xxx.control.net.NetWorkException
import com.xxx.control.net.RetrofitManager
import kotlinx.coroutines.*
import retrofit2.HttpException
import java.io.IOException

/**
 * 对ViewModel的一个协程拓展函数
 */
fun ViewModel.launch(
    block: suspend CoroutineScope.() -> Unit,
    onError: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
) {
    viewModelScope.launch(CoroutineExceptionHandler { _, e -> onError(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete.invoke()
        }
    }

}

fun ViewModel.async(
    block: suspend CoroutineScope.() -> Unit,
    onError: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
) {
    viewModelScope.async(CoroutineExceptionHandler { _, e -> onError(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete.invoke()
        }
    }

}

fun ViewModel.showException(e: Throwable) {
    var code = 0
    var errorMsg = e.message
    if (e is Exception) {
        if (e is IOException) {

            //errorMsg = "Please check your network status"
        } else if (e is HttpException) {
            /** 网络异常，http 请求失败，即 http 状态码不在 [200, 300) 之间, such as: "server internal error".  */
//            errorMsg = ((HttpException) e).response().message();
            e.response()?.apply {
                code = code()
                if (errorBody() != null) {
                    errorMsg = errorBody()!!.string()
                }
            }


        } else if (e is NetWorkException) {
            code = e.code
            errorMsg = e.message
        } else {
            /** 其他未知错误  */
            errorMsg = if (!TextUtils.isEmpty(e.message)) e.message else "unknown error"
        }
//            Timber.e("error:%s", errorMsg)
        if (errorMsg == "") {
            errorMsg = e.message
        }
        e.printStackTrace()
    }

}

/**
 * 对AppCompatActivity的一个协程拓展函数
 */
fun AppCompatActivity.launch(
    block: suspend CoroutineScope.() -> Unit,
    onError: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
) {
    lifecycleScope.launch(CoroutineExceptionHandler { _, e -> onError(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete.invoke()
        }
    }

}


fun <T> createApi(cls: Class<T>): T {
    return RetrofitManager.build().create(cls)
}


fun BaseVMActivity<out ViewBinding, out BaseViewModel>.showException(e: Throwable) {

    var code = 0
    var errorMsg = e.message
    if (e is Exception) {
        if (e is IOException) {
            /** 没有网络  */

            errorMsg = "Network not connected"
        } else if (e is HttpException) {
            /** 网络异常，http 请求失败，即 http 状态码不在 [200, 300) 之间, such as: "server internal error".  */
//            errorMsg = ((HttpException) e).response().message();
            e.response()?.apply {
                code = code()
                if (errorBody() != null) {
                    errorMsg = errorBody()!!.string()
                }
            }


        } else if (e is NetWorkException) {
            code = e.code
            errorMsg = e.message
        } else {
            /** 其他未知错误  */
            errorMsg = if (!TextUtils.isEmpty(e.message)) e.message else "unknown error"
        }
//        Timber.e("error:%s", errorMsg)
        if (errorMsg == "") {
            errorMsg = e.message
        }
//        loadFailure(code, errorMsg!!)
        e.printStackTrace()
    }

}


fun <T> AppCompatActivity.async(
    block: suspend CoroutineScope.() -> T,
    onError: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
): Deferred<T> {
    return lifecycleScope.async(CoroutineExceptionHandler { _, e -> onError(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete.invoke()
        }
    }

}

fun BaseVMFragment<out ViewBinding, out BaseViewModel>.showException(
    e: Throwable
) {


    var code = 0
    var errorMsg = e.message
    if (e is Exception) {
        if (e is IOException) {
            /** 没有网络  */

            //errorMsg = "Please check your network status"
        } else if (e is HttpException) {
            /** 网络异常，http 请求失败，即 http 状态码不在 [200, 300) 之间, such as: "server internal error".  */
//            errorMsg = ((HttpException) e).response().message();
            e.response()?.apply {
                code = code()
                if (errorBody() != null) {
                    errorMsg = errorBody()!!.string()
                }
            }


        } else if (e is NetWorkException) {
            code = e.code
            errorMsg = e.message
        } else {
            /** 其他未知错误  */
            errorMsg = if (!TextUtils.isEmpty(e.message)) e.message else "unknown error"
        }
//        Timber.e("error:%s", errorMsg)
        if (errorMsg == "") {
            errorMsg = e.message
        }
//        loadFailure(code, errorMsg!!)
        e.printStackTrace()
    }

}

fun Fragment.async(
    block: suspend CoroutineScope.() -> Unit,
    onError: (e: Throwable) -> Unit = {},
    onComplete: () -> Unit = {}
) {
    //在fragment中使用viewLifecycleOwner https://mp.weixin.qq.com/s/_2YSV_JsjDJ7CuHJngMbqQ
    viewLifecycleOwner.lifecycleScope.async(CoroutineExceptionHandler { _, e -> onError(e) }) {
        try {
            block.invoke(this)
        } finally {
            onComplete
        }
    }

}